'use client';

import { observer } from 'mobx-react-lite';
import { useEffect, useState } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import Button, { ButtonSize, ButtonVariant } from '@/components/button/Button';
import {
  GridListItemWrapper,
  GridListWrapper,
} from '@/components/grid/GridListUtils';
import ImageWithFallback, {
  ImageSize,
} from '@/components/image/ImageWithFallback';
import Link from '@/components/link/Link';
import SongRow from '@/components/song/SongRow';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import TitleText from '@/components/title/TitleText';
import usePageViewLog from '@/hooks/usePageViewLog';
import { PauseIcon, PlayIcon, ShareArrowIcon } from '@/icons';
import { ContextType } from '@/logging/contextTypes';
import { Clip } from '@/state/clipStore';
import { getClipTitle } from '@/utils/clip';
import { SMALL_IMAGE } from '@/utils/constants';
import { shareRadio } from '@/utils/download';

interface RadioPageClientProps {
  clip: Clip;
}

const RadioPageClient: React.FC<RadioPageClientProps> = observer(({ clip }) => {
  const {
    playbar: playbarStore,
    library,
    queue: queueStore,
    clips,
    menus,
  } = useStores();
  const [similarClips, setSimilarClips] = useState<Clip[]>([]);
  const [isSimilarDataLoaded, setIsSimilarDataLoaded] = useState(false);

  async function fetchSimilarClips() {
    try {
      const { data } = (await library.apiClient.GET(`/api/clips/get_similar/`, {
        params: { query: { id: clip.id, count: 50 } },
      })) as any;
      if (data && data.similar_clips) {
        const filteredClips: Clip[] = data.similar_clips.filter(
          (c: Clip) => c.id !== clip.id
        );
        setSimilarClips(filteredClips);
        setIsSimilarDataLoaded(true);
        clips.updateClips([clip, ...filteredClips]);
      }
    } catch (error) {
      setSimilarClips([]);
      console.error('Error fetching similar clips:', error);
    }
  }

  useEffect(() => {
    fetchSimilarClips();
  }, []);

  useEffect(() => {
    menus.setCurrentClip(playbarStore.clip || null);
  }, [playbarStore.clip]);

  usePageViewLog({
    actionName: 'PageViewed',
    componentContext: 'song-radio',
    principalObjectType: 'clip',
    principalObjectValue: clip.id,
  });

  return (
    <main className='flex max-w-full flex-1 flex-col overflow-y-auto'>
      <div className='flex max-w-full flex-1 overflow-y-auto'>
        <div className='flex max-w-full flex-1 flex-col'>
          <div className='flex flex-row items-end justify-end gap-4 p-6 py-4 md:gap-0 md:py-6'>
            <ImageWithFallback
              imageSize={SMALL_IMAGE}
              src={clip?.image_url}
              alt='Radio cover art'
              className='ml-0 h-auto w-[80px] rounded-md sm:mb-4 sm:ml-0 sm:w-[80px] md:mb-0 md:ml-0 md:w-[180px] lg:ml-6 lg:w-[180px] xl:w-[180px]'
            />
            <div className='flex flex-1 flex-col justify-end gap-2 pl-0 md:pl-8'>
              <div className='line-clamp-2 flex flex-row justify-center lg:justify-start'>
                <TitleText text={`${getClipTitle(clip)} Radio`} />
              </div>
              {(!!clip.display_name || !!clip.handle) && (
                <span className='flex flex-nowrap items-center justify-center font-sans text-sm font-medium lg:justify-start'>
                  <ImageWithFallback
                    src={clip.avatar_image_url}
                    alt='Profile'
                    className='mr-1 inline-block h-3 w-3 rounded-full align-middle'
                    imageSize={ImageSize.SMALL}
                  />
                  <Link href={`/@${clip.handle}`}>
                    <span className='break-word line-clamp-1'>
                      {clip.display_name || clip.handle || ''}
                    </span>
                  </Link>
                </span>
              )}
            </div>
            <div className='flex flex-col justify-end pr-0 md:pr-8'>
              <div className='flex flex-col justify-end pr-0 md:pr-8'>
                <div className='-mb-1 flex flex-row items-center justify-center gap-2 md:items-end md:justify-end'>
                  <Button
                    variant={ButtonVariant.Primary}
                    size={ButtonSize.Large}
                    icon={<ShareArrowIcon />}
                    onClick={() => {
                      shareRadio(clip.id);
                    }}
                  />
                  <Button
                    variant={ButtonVariant.Primary}
                    size={ButtonSize.Large}
                    icon={
                      playbarStore.loadingStream ? (
                        <SpinnerSVG className='h-[14px] w-[14px]' />
                      ) : playbarStore.isPlaying &&
                        queueStore.isCurrentContext(
                          clip.id,
                          ContextType.SongRadio
                        ) ? (
                        <PauseIcon />
                      ) : (
                        <PlayIcon />
                      )
                    }
                    onClick={() => {
                      const radioClips = [clip, ...similarClips];
                      if (!queueStore.isPlaylistCurrentContext(clip.id)) {
                        queueStore.setPlayContext({
                          clips: radioClips,
                          currentIndex: 0,
                          contextType: ContextType.SongRadio,
                          contextId: clip.id,
                        });
                      }
                      playbarStore.togglePlay();
                    }}
                  />
                </div>
              </div>
            </div>
          </div>
          <div className='flex flex-1 flex-col overflow-y-auto p-6 py-4 md:py-6'>
            <div>
              {isSimilarDataLoaded ? (
                [clip, ...similarClips].length > 0 ? (
                  <GridListWrapper
                    aria-label={`${clip.title} Radio`}
                    items={
                      [clip, ...similarClips].map(
                        (c: Clip) => clips.clipById[c.id]
                      ) || []
                    }
                  >
                    {(song: any) => {
                      return (
                        <GridListItemWrapper>
                          <SongRow
                            key={song.id}
                            clip={song}
                            onClick={() => {
                              menus.setCurrentClip(clip);
                            }}
                            contextType={ContextType.SongRadio}
                            contextId={clip.id}
                            index={(
                              [clip, ...similarClips].map(
                                (c: Clip) => clips.clipById[c.id]
                              ) || []
                            ).indexOf(song)}
                            onPlay={() => {
                              if (playbarStore.clip?.id === song.id) {
                                playbarStore.togglePlay();
                              } else {
                                const fullClipList =
                                  [clip, ...similarClips].map(
                                    (c: Clip) => clips.clipById[c.id]
                                  ) || [];
                                queueStore.setPlayContext({
                                  clips: fullClipList,
                                  currentIndex: fullClipList.indexOf(song),
                                  contextType: ContextType.SongRadio,
                                  contextId: clip.id,
                                });
                                playbarStore.playClip(song);
                              }
                            }}
                            showUser={true}
                          />
                        </GridListItemWrapper>
                      );
                    }}
                  </GridListWrapper>
                ) : (
                  <p>
                    This song doesn&apos;t have a radio currently. Explore
                    another song&apos;s radio.
                  </p>
                )
              ) : (
                <div className='flex items-center justify-center'>
                  <SpinnerSVG />
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </main>
  );
});

export default RadioPageClient;
